package org.example.java8.future;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 夏焰波
 * @date 2020-07-15 23:30
 */
//35CompletableFuture流水线工作，join多个异步任务详细讲解
public class CompletableFutureInAction6 {
    private final static Random RANDOM = new Random(System.currentTimeMillis());

    public static void main(String[] args) throws InterruptedException {
        //实现工厂接口，设置守护线程
        Executor executor = Executors.newFixedThreadPool(2, r -> {
            Thread t = new Thread(r);
            //设置非守护线程
            t.setDaemon(false);
            return t;
        });

        List<Integer> productionIDs = Arrays.asList(1, 2, 3, 4, 5);
        //Stream<CompletableFuture<Double>> completableFutureStream = productionIDs.stream().map(i -> CompletableFuture.supplyAsync(
        //        () -> queryProduction(i), executor)
        //);
        //Stream<CompletableFuture<Double>> multiplyFuture = completableFutureStream.map(future -> future.thenApply(CompletableFutureInAction6::multiply));
        //List<Double> result = multiplyFuture.map(CompletableFuture::join).collect(Collectors.toList());

        List<Double> result = productionIDs.stream()
                .map(i -> CompletableFuture.supplyAsync(() -> queryProduction(i), executor))
                .map(future -> future.thenApply(CompletableFutureInAction6::multiply))
                .map(CompletableFuture::join)
                .collect(Collectors.toList());

        System.out.println(result);

    }

    private static double multiply(double value) {
        return value * 10.0d;
    }

    private static double queryProduction(int i) {
        return CompletableFutureInAction6.get();
    }

    private static double get() {
        try {
            Thread.sleep(RANDOM.nextInt(5000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        double v = RANDOM.nextDouble();
        System.out.println(v);
        return v;
    }
}
